package com.aispeech.astools.recorder;


import android.app.Application;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import com.aispeech.astools.jni.SerialPort;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

/**
 * @author rain  07.10 2019
 */

public class SerialRecord implements BaseRecord {

    private final String TAG = "SerialRecord";

    private SerialPort mSerialPort = null;

    protected OutputStream mOutputStream;
    private InputStream mInputStream;

    private ReadThread mReadThread;
    private HandlerThread mSendThread;
    private Handler mSendHandler;

    private boolean isRead = true;
    private final int MSG_SEND_DATA = 0;

    private final int READ_BUF_LEN = 640;

    private RecordListener mListener;

    private class ReadThread extends Thread {

        @Override
        public void run() {
            super.run();
            Log.d(TAG, "ReadThread run ");
            try {
                isRead = true;
                while (isRead) {
                    int size;

                    byte[] buffer = new byte[READ_BUF_LEN];
                    if (mInputStream == null) {
                        return;
                    }
                    size = mInputStream.read(buffer);
                    if (size > 0) {
                        mListener.onBuffer(Arrays.copyOfRange(buffer, 0, size));
                    }
                }

                if (mSerialPort != null) {
                    mSerialPort.close();
                    mSerialPort = null;
                }
            } catch (Exception e) {
                e.printStackTrace();
                mListener.onError(e.toString());
            }
        }
    }

    private void initDataThread() {
        Log.d(TAG, "initDataThread");
        mReadThread = new ReadThread();
        mReadThread.start();

        mSendThread = new HandlerThread("SerialSendThread");
        mSendThread.start();
        mSendHandler = new Handler(mSendThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case MSG_SEND_DATA:
                        try {
                            String sendData = (String) msg.obj;
                            if (mOutputStream != null && !TextUtils.isEmpty(sendData)) {
                                mOutputStream.write(sendData.getBytes());
                            } else {
                                return;
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            mListener.onError(e.toString());
                            return;
                        }
                        break;
                }
            }
        };
    }

    @Override
    public void init(Application appContext, RecordListener listener) {
        Log.d(TAG, "init: ");
        mListener = listener;
    }

    @Override
    @Deprecated
    public void start() {

    }

    public void sendData(String data) {
        Log.d(TAG, "sendData with: data = " + data + "");
        Message.obtain(mSendHandler, MSG_SEND_DATA, data).sendToTarget();
    }

    public boolean start(String serialPort, int baudRate) {
        Log.d(TAG, "start with: serialPort = " + serialPort + ", baudRate = " + baudRate + "");
        try {
            mSerialPort = new SerialPort(new File(serialPort), baudRate, 0);
            mOutputStream = mSerialPort.getOutputStream();
            mInputStream = mSerialPort.getInputStream();
            initDataThread();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            mListener.onError(e.toString());
        }
        return false;
    }

    @Override
    public void stop() {
        Log.d(TAG, "stop");
        isRead = false;
    }

    @Override
    public void destroy() {
        Log.d(TAG, "destroy: ");

        if (null != mSendThread) {
            Looper looper = mSendThread.getLooper();
            if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2) {
                if (null != looper) {
                    looper.quitSafely();
                }
            } else {
                if (null != looper) {
                    looper.quit();
                }
            }
        }

        if (null != mSendHandler) {
            mSendHandler.removeCallbacksAndMessages(null);
            Log.w(TAG, "destroy: mDataProcessThread : " + mSendThread.getState());
        }
    }
}
